#include <GLFW/glfw3.h>
#include <iostream>

using std::cout;
using std::cerr;
using std::endl;

#define TITLE "Tutorial 2 - Simple 2D Shapes"

void glfwErrorCallback(int error, const char* description);

int main(int argc, char** argv)
{
  glfwSetErrorCallback(glfwErrorCallback);

  if (!glfwInit())
    return 0;

  // We require an OpenGL context of version 4.3.
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

  // Setting the buffer sizes.
  glfwWindowHint(GLFW_RED_BITS, 8);
  glfwWindowHint(GLFW_GREEN_BITS, 8);
  glfwWindowHint(GLFW_BLUE_BITS, 8);
  glfwWindowHint(GLFW_ALPHA_BITS, 8);

  // Depth buffer not needed in this tutorial.
  glfwWindowHint(GLFW_DEPTH_BITS, 0);  
  // We don't need the stencil buffer either.
  glfwWindowHint(GLFW_STENCIL_BITS, 0);

  // Create a window with the specified hints.
  GLFWwindow* window = glfwCreateWindow(640, 480, TITLE, NULL, NULL);
  if (!window)
  {
    glfwTerminate();
    return 0;
  }

  // Makes the OpenGL context of the passed window active.
  glfwMakeContextCurrent(window);

  // The main loop. While the window is not closed we catch events and react to
  // them.
  while (!glfwWindowShouldClose(window))
  {

    // Doublebuffering - Swap back and front buffer.
    glfwSwapBuffers(window);

    // Handle new events.
    glfwPollEvents();
  }

  // Close all windows and uninitialize GLFW.
  glfwTerminate();

  return 1;
}

void glfwErrorCallback(int error, const char* description)
{
  cerr << "GLFW Error: " << description << " (" << error << ")." << endl;
}
